# coding:utf8
import keras
from keras.models import Sequential,Model
import matplotlib.pyplot as plt
from keras.layers import Dense,Dropout
from keras.layers.recurrent import LSTM
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
SEED = 22
np.random.seed(SEED)
# FIXME:文章链接:http://resuly.me/2017/08/16/keras-rnn-tutorial/
class Rnn_bike():
    def __init__(self,fi):
        self.file = fi
    # CORE:处理步骤
    def _read_data(self,sequence_length=20):
        data = pd.read_csv(self.file)
        data = data.loc[:,'num']  # 取一系列
        # REW:取20个为一序列
        result = []
        for index in range(len(data)-sequence_length):
            # print(data[index:index+sequence_length])
            result.append(data[index:index+sequence_length])
        data = np.asarray(result,dtype='float32')
        # data = (data - data.mean()) / data.std()
        label = data[:,-1]
        data = data[:,:-1]  #FAQ:没有转换维度?
        print('data',data,'\n')
        print('label',label,'\n')
        return train_test_split(data,label,test_size=0.2,random_state=SEED)

    def _build_model(self):
        model = Sequential()
        layers = [1,50,100,1]
        model.add(LSTM(layers[1],
                       input_shape=(None,1),
                       return_sequences=True))  # return_sequences 传给自己层同时，也one to one将每次的计算结果都同时传给下一层
        model.add(Dropout(0.4,seed=SEED))
        model.add(LSTM(layers[2],
                       return_sequences=False))
        model.add(Dropout(0.02))
        model.add(Dense(layers[3],
                        activation="linear")) # 输出值 REW:下一层只需要最后一个输入序列的预测结果，所以在最后一个值计算完成后，才将结果传同时给下一层

        model.compile(optimizer='rmsprop',loss='mse')

        return model

    def _fit(self):
        x_train, x_test, y_train, y_test = self._read_data()
        model = self._build_model()
        model.fit(x_train,y_train,batch_size=20,epochs=5,validation_split=0.2)

        y_pred = model.predict(x_test)
        y_pred = np.reshape(y_pred,(y_pred.size,))

        return x_test,y_test,y_pred
    def draw(self):
        x_test,y_test, y_pred = self._fit()
        try:
            figure = plt.figure()
            ax = figure.add_subplot(111)
            ax.plot(y_pred[:100,0],c='r')
            ax.plot(y_test[:100,0],c='g')
            ax.ylim(-1,1)
            plt.show()
        except:
            pass


if __name__ == "__main__":
    fi = "D:\hiicy\documents\\bike_rnn.csv"
    rnn = Rnn_bike(fi)
    rnn.draw()